/**
编写一段程序来查找第 n 个超级丑数。

超级丑数是指其所有质因数都是长度为 k 的质数列表 primes 中的正整数。

示例:

输入: n = 12, primes = [2,7,13,19]
输出: 32 
解释: 给定长度为 4 的质数列表 primes = [2,7,13,19]，前 12 个超级丑数序列为：[1,2,4,7,8,13,14,16,19,26,28,32] 。
说明:

1 是任何给定 primes 的超级丑数。
 给定 primes 中的数字以升序排列。
0 < k ≤ 100, 0 < n ≤ 106, 0 < primes[i] < 1000 。
第 n 个超级丑数确保在 32 位有符整数范围内。


来源：力扣（LeetCode）
链接：https://leetcode-cn.com/problems/super-ugly-number
著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
*/
import "container/heap"

type UglyNums []int

func (u *UglyNums) Push(x interface{}) {
    *u = append(*u, x.(int))
}

func (u *UglyNums) Pop() interface{} {
    n := len(*u)
    x := (*u)[n-1]

    (*u) = (*u)[0:n-1]
    return x
}

func (u UglyNums) Swap(i, j int) {
    u[i], u[j] = u[j], u[i]
}

func (u UglyNums) Less(i, j int) bool{
    return u[i] < u[j]
}

func (u UglyNums) Len() int {
    return len(u)
}

func nthSuperUglyNumber(n int, primes []int) int {
    if n == 0 || n == 1{
        return n
    }
    h := new(UglyNums)

    heap.Push(h, 1)
    n--

    for n > 0 {
        x := heap.Pop(h).(int)
        
        for h.Len() > 0 && x == (*h)[0] { //去除重复的数据
            heap.Pop(h)
        }

        for i := 0; i < len(primes); i++ {
            heap.Push(h, x * primes[i])
        }
        n --
    }
    return heap.Pop(h).(int)
}